package com.kssoft.ebd.spider.http;

import com.alibaba.fastjson.JSON;
import org.apache.http.NameValuePair;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.*;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.TrustStrategy;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

import javax.net.ssl.SSLContext;
import java.security.cert.X509Certificate;
import java.util.*;

public class HttpClientUtil {

    private static final int TIMEOUT = 10000; // ms


    // 创建不验证 SSL 的 HttpClient
    private static CloseableHttpClient createHttpClient() throws Exception {
        TrustStrategy acceptingTrustStrategy = (X509Certificate[] chain, String authType) -> true;

        SSLContext sslContext = org.apache.http.ssl.SSLContexts.custom()
                .loadTrustMaterial(null, acceptingTrustStrategy)
                .build();

        SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
                sslContext,
                NoopHostnameVerifier.INSTANCE);

        RequestConfig config = RequestConfig.custom()
                .setConnectTimeout(TIMEOUT)
                .setConnectionRequestTimeout(TIMEOUT)
                .setSocketTimeout(TIMEOUT)
                .build();

        return HttpClients.custom()
                .setSSLSocketFactory(sslsf)
                .setDefaultRequestConfig(config)
                .build();
    }

    private static void setHeaders(HttpRequestBase request, Map<String, String> headers, Map<String, String> cookies) {
        if (headers != null) {
            for (Map.Entry<String, String> entry : headers.entrySet()) {
                request.setHeader(entry.getKey(), entry.getValue());
            }
        }

        if (cookies != null && !cookies.isEmpty()) {
            StringBuilder cookieStr = new StringBuilder();
            for (Map.Entry<String, String> cookie : cookies.entrySet()) {
                if (cookieStr.length() > 0) cookieStr.append("; ");
                cookieStr.append(cookie.getKey()).append("=").append(cookie.getValue());
            }
            request.setHeader("Cookie", cookieStr.toString());
        }
//        System.out.println("------------------------请求头：" + JSON.toJSONString(request.getAllHeaders()));
    }

    // GET 请求
    public static String doGet(String url, Map<String, String> params, Map<String, String> cookies, Map<String, String> headers) throws Exception {
        StringBuilder fullUrl = new StringBuilder(url);
        if (params != null && !params.isEmpty()) {
            // 判断 URL 是否已经包含参数（即是否已有 ?）
            boolean hasParams = url.contains("?");
            for (Map.Entry<String, String> entry : params.entrySet()) {
                // 如果已经有参数，使用 & 追加；否则使用 ? 开始参数
                if (hasParams) {
                    fullUrl.append("&");
                } else {
                    fullUrl.append("?");
                    hasParams = true;
                }
                fullUrl.append(entry.getKey())
                        .append("=")
                        .append(java.net.URLEncoder.encode(entry.getValue() == null ? "" : entry.getValue(), "UTF-8"));
            }
        }

        HttpGet request = new HttpGet(fullUrl.toString());
        setHeaders(request, headers, cookies);
//        System.out.println("--------------------get请求参数：" + fullUrl);

        try (CloseableHttpClient client = createHttpClient();
             CloseableHttpResponse response = client.execute(request)) {
            return EntityUtils.toString(response.getEntity(), "UTF-8");
        }
    }

    // POST 请求 (application/x-www-form-urlencoded)
    public static String doPost(String url, Map<String, String> params, Map<String, String> cookies, Map<String, String> headers) throws Exception {
        HttpPost request = new HttpPost(url);
        setHeaders(request, headers, cookies);
//        System.out.println("----------------------doPostFrom请求url：" + url);
//        System.out.println("----------------------doPostFrom请求参数：" + JSON.toJSONString(params));

        if (params != null && !params.isEmpty()) {
            List<NameValuePair> nvps = new ArrayList<>();
            for (Map.Entry<String, String> entry : params.entrySet()) {
                nvps.add(new BasicNameValuePair(entry.getKey(), entry.getValue() == null ? "" : entry.getValue()));
            }
            request.setEntity(new UrlEncodedFormEntity(nvps, "UTF-8"));
        }

        try (CloseableHttpClient client = createHttpClient();
             CloseableHttpResponse response = client.execute(request)) {
            return EntityUtils.toString(response.getEntity(), "UTF-8");
        }
    }
    // POST JSON 请求
    public static String doPostJson(String url, String jsonBody, Map<String, String> cookies, Map<String, String> headers) throws Exception {
        HttpPost request = new HttpPost(url);
        setHeaders(request, headers, cookies);

//        System.out.println("----------------------doPostJson请求url：" + url);
//        System.out.println("----------------------doPostJson请求参数：" + jsonBody);
        // 设置 JSON 请求体
        StringEntity entity = new StringEntity(jsonBody, "UTF-8");
        entity.setContentType("application/json");
        request.setEntity(entity);

        try (CloseableHttpClient client = createHttpClient();
             CloseableHttpResponse response = client.execute(request)) {
            return EntityUtils.toString(response.getEntity(), "UTF-8");
        }
    }
        public static void main(String[] args) throws Exception {
            HttpClientUtil httpClient = new HttpClientUtil();

            String json = "{ \"username\": \"testuser\", \"password\": \"123456\" }";

            Map<String, String> cookies = new HashMap<>();
            cookies.put("session_id", "abcdefg");
            Map<String, String> headers = new HashMap<>();
            headers.put("User-Agent", "HttpClient/4.5.10");

            String result = httpClient.doPostJson("https://httpbin.org/post", json, cookies, headers);
            System.out.println("POST JSON Result:\n" + result);
        }

}
